#pragma once

#include "DLL.h"
#include "Bezier.h"
#include <map>
#include <MyViews/Tool.h>

namespace My {

class BezierEditor;

class DLL_API DrawFirstPoint : public Manipulator 
{
public:
	DrawFirstPoint(BezierEditor &, CPoint p);
public:
	virtual void Manipulate(UINT, CPoint);
	virtual void Apply(UINT, CPoint);
	virtual void PaintRect(CDC *, const CRect &);
private:
	BezierEditor &	m_Editor;
	BezierNode		m_Node;
};

class DLL_API DrawNextPoint : public Manipulator 
{
public:
	DrawNextPoint(BezierEditor &, Bezier &, Size dir, CPoint p);
public:
	virtual void Manipulate(UINT, CPoint);
	virtual void Apply(UINT, CPoint);
	virtual void PaintRect(CDC *, const CRect &);
private:
	BezierEditor &	m_Editor;
	Size			m_Dir;
	Bezier &		m_Curve;
	BezierNode		m_Nodes[2];
};

class DLL_API DragControlPoint : public Manipulator
{
public:
	DragControlPoint(BezierEditor &, Bezier &,	
		Size inode,	Size icontrol, CPoint start, BezierNode * pHint = 0);
public:
	virtual void Manipulate(UINT, CPoint);
	virtual void Apply(UINT, CPoint);
	virtual void PaintRect(CDC *, const CRect &);
private:
	BezierEditor &	m_Editor;
	Bezier &		m_Curve;
	BezierNode		m_Node;
	Size			m_NodeIndex;
	Size			m_ControlIndex;
	point<float>	m_Start;
	point<float>	m_Old;
};

class DLL_API DragNodes : public Manipulator
{
public:
	DragNodes(BezierEditor &, CPoint);
public:
	virtual void Manipulate(UINT, CPoint);
	virtual void Apply(UINT, CPoint);
	virtual void PaintRect(CDC *, const CRect &);
private:
	typedef std::pair<Bezier *, Size>			NodeIndex;
	typedef std::pair<BezierNode, BezierNode>	NodePair;
	typedef std::map<NodeIndex, NodePair>		NodeMap; 
private:
	BezierEditor &	m_Editor;
	NodeMap			m_Nodes;
	point<float>	m_Start;
	BezierNode		m_Old;
};

class DLL_API DragCurve : public Manipulator {
public:
	DragCurve(BezierEditor &, Bezier &, float t, CPoint start);
public:
	virtual void Manipulate(UINT, CPoint);
	virtual void Apply(UINT, CPoint);
	virtual void PaintRect(CDC *, const CRect &);
private:
	BezierEditor &	m_Editor;
	Bezier &		m_Curve;
	point<float>	m_Start;
	Size			m_Indexes[2];
	BezierNode		m_Nodes[2];
	point<float>	m_Controls[2];
	float			m_Coefs[2];
};

class DLL_API SelectRange : public Manipulator {
public:
	SelectRange(BezierEditor &, CPoint p);
public:
	virtual void Manipulate(UINT, CPoint);
	virtual void Apply(UINT, CPoint);
	virtual void PaintRect(CDC *, const CRect &);
private:
	BezierEditor &	m_Editor;
	point<float>	m_Start;
	rect<float>		m_Range;
};

} // My